import 'package:flutter/cupertino.dart';

import 'package:provider/provider.dart';

import 'base_view_model.dart';

/// 空视图 builder方法 回调函数
// typedef Builder_w = Widget Function(BuildContext context);
// 路由操作枚举
enum RouteChangeType { push, pop }

class ProviderWidget<T extends ChangeNotifier> extends StatefulWidget {
  static RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
  final ValueWidgetBuilder<T> builder;
  final T model;
  final Widget? child;
  final Function(T model)? onModelReady;
  final bool autoDispose;
  final bool autoInitState;
  final bool? autoLoadData;
  final Function? initState;
  final Function? dispose;

  const ProviderWidget(
      {Key? key,
      required this.builder,
      required this.model,
      this.child,
      this.onModelReady,
      this.autoDispose = true,
      this.autoInitState = true,
      this.autoLoadData = true,
      this.initState,
      this.dispose})
      : super(key: key);

  _ProviderWidgetState<T> createState() => _ProviderWidgetState<T>();
}

class _ProviderWidgetState<T extends ChangeNotifier>
    extends State<ProviderWidget<T>> with RouteAware {
  late T model;
  late final AppLifecycleListener _listener;


  @override
  void initState() {
    model = widget.model;
    widget.onModelReady?.call(model);
    super.initState();

    if (model is BaseViewModel) {
      (model as BaseViewModel).setBuildContext(context);
      (model as BaseViewModel).autoLoadData = widget.autoLoadData ?? false;
      if (widget.autoInitState == true) {
        (model as BaseViewModel).initState();
      }
    }
    if (null != widget.initState) {
      widget.initState?.call();
    }
    _listener = AppLifecycleListener(
      onShow: () => (model as BaseViewModel).onShow(),
      onResume: () => (model as BaseViewModel).onResume(),
      onHide: () => (model as BaseViewModel).onHide(),
      onInactive: () => (model as BaseViewModel).onInactive(),
      onPause: () => (model as BaseViewModel).onPause(),
      onDetach: () => (model as BaseViewModel).onDetach(),
      onRestart: () => (model as BaseViewModel).onRestart(),
      onExitRequested: () => (model as BaseViewModel).onExitRequested(),
      onStateChange: (state) => (model as BaseViewModel).onStateChange(state),
    );
  }

  @override
  void dispose() {
    _listener.dispose();
    ProviderWidget.routeObserver.unsubscribe(this);
    super.dispose();
    if (widget.autoDispose) model.dispose();
    if (null != widget.dispose) {
      widget.dispose?.call();
    }
  }

  @override
  void didChangeDependencies() {
    ModalRoute? route = ModalRoute.of(context);

    super.didChangeDependencies();
    if (route != null) {
      ProviderWidget.routeObserver.unsubscribe(this);
    }
    // 注册监听
    ProviderWidget.routeObserver.subscribe(this, route as PageRoute);
  }

  @override
  void didPush() {
    (model as BaseViewModel).viewWillAppear(RouteChangeType.push);
    super.didPush();
  }

  @override
  void didPushNext() {
    // TODO: implement didPushNext
    super.didPushNext();
  }

  @override
  void didPop() {
    (model as BaseViewModel).viewWillAppear(RouteChangeType.pop);
    super.didPop();
  }

  @override
  void didPopNext() {
    // TODO: implement didPopNext
    (model as BaseViewModel).viewWillAppear(RouteChangeType.pop);
    super.didPopNext();
  }


  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<T>.value(
      value: model,
      child: Consumer<T>(
        builder: widget.builder,
        child: widget.child,
      ),
    );
  }
}

class ProviderWidget2<A extends ChangeNotifier, B extends ChangeNotifier>
    extends StatefulWidget {
  final Widget Function(BuildContext context, A model1, B model2, Widget? child)
      builder;
  final A model1;
  final B model2;
  final Widget? child;
  final Function(A model1, B model2)? onModelReady;
  final bool? autoDispose;

  ProviderWidget2({
    Key? key,
    required this.builder,
    required this.model1,
    required this.model2,
    this.child,
    this.onModelReady,
    this.autoDispose,
  }) : super(key: key);

  _ProviderWidgetState2<A, B> createState() => _ProviderWidgetState2<A, B>();
}

class _ProviderWidgetState2<A extends ChangeNotifier, B extends ChangeNotifier>
    extends State<ProviderWidget2<A, B>> {
  late A model1;
  late B model2;

  @override
  void initState() {
    model1 = widget.model1;
    model2 = widget.model2;
    widget.onModelReady?.call(model1, model2);
    super.initState();
  }

  @override
  void dispose() {
    if (widget.autoDispose == true) {
      model1.dispose();
      model2.dispose();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<A>.value(value: model1),
        ChangeNotifierProvider<B>.value(value: model2),
      ],
      child: Consumer2<A, B>(
        builder: widget.builder,
        child: widget.child,
      ),
    );
  }
}
